package py.com.alfa.escriba.web.rest.impl;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

import py.com.alfa.escriba.config.EscribaApplicationContextProvider;
import py.com.alfa.escriba.config.HttpHeaderConfig;
import py.com.alfa.escriba.exception.ErrorCode;
import py.com.alfa.escriba.exception.ServiceException;
import py.com.alfa.escriba.persistence.dto.EscribanosDTO;
import py.com.alfa.escriba.persistence.dto.PersonaInfoParaControlDTO;
import py.com.alfa.escriba.persistence.dto.admin.ClienteDTO;
import py.com.alfa.escriba.persistence.dto.admin.ClienteInfoDTO;
import py.com.alfa.escriba.persistence.dto.admin.DomicilioDTO;
import py.com.alfa.escriba.persistence.dto.admin.FuncionalidadDTO;
import py.com.alfa.escriba.persistence.dto.admin.PerfilDTO;
import py.com.alfa.escriba.persistence.dto.admin.PersonaDTO;
import py.com.alfa.escriba.persistence.dto.admin.PersonaInfoDTO;
import py.com.alfa.escriba.persistence.dto.admin.TelefonoDTO;
import py.com.alfa.escriba.persistence.dto.admin.UsuarioDTO;
import py.com.alfa.escriba.persistence.dto.query.PersonaQueryDTO;
import py.com.alfa.escriba.web.interceptor.BeanNames;
import py.com.alfa.escriba.web.interceptor.InvocationContext;
import py.com.alfa.escriba.web.rest.EscribaService;
import py.com.alfa.escriba.web.rest.secure.AdminSecureRESTService;
import py.com.alfa.escriba.web.services.AdminService;
import py.com.alfa.escriba.web.services.FuncionalidadService;
import py.com.alfa.escriba.web.services.PerfilService;
import py.com.alfa.escriba.web.services.UsuarioService;

public class AdminSecureRESTServiceImpl implements AdminSecureRESTService {

	private Logger log = LoggerFactory.getLogger(getClass());
	private ApplicationContext ctx;
	private AdminService admin;
	private UsuarioService daoUsuario;
	private FuncionalidadService daoFuncionalidad;
	private PerfilService daoPerfil;
	private InvocationContext ic;
	private HttpHeaderConfig config;
	private Logger logger = LoggerFactory.getLogger(getClass());

	
	public AdminSecureRESTServiceImpl() {
		this.ctx = EscribaApplicationContextProvider.getContext();
		this.admin = (AdminService)this.ctx.getBean(EscribaService.ADMIN_SERVICE);
		this.daoUsuario = (UsuarioService) ctx.getBean("usuarioService");
		this.daoFuncionalidad = (FuncionalidadService) ctx.getBean("funcionalidadService");
		this.daoPerfil = (PerfilService) ctx.getBean("perfilService");
		this.config = (HttpHeaderConfig) ctx.getBean(BeanNames.HTTP_HEADERS_BEAN);
	}
	
	@Override
	public PersonaDTO obtenerPersona(Long id) throws ServiceException {
		this.log.debug("===== INI obtenerPersona ===");
		PersonaDTO dto = this.admin.obtenerPersona(id);
		this.log.debug("===== FIN obtenerPersona ===\n {}", dto.toString());
		return dto;
		
	}
	
	@Override
	public EscribanosDTO obtenerEscribano(Long id) throws ServiceException {
		this.log.debug("===== INI obtenerEscribano ===");
		EscribanosDTO dto = this.admin.obtenerEscribano(id);
		this.log.debug("===== FIN obtenerEscribano ===\n {}", dto.toString());
		return dto;
		
	}

	@Override
	public PersonaDTO crearPersona(PersonaDTO dto, HttpServletRequest request) throws ServiceException {
		this.log.debug("===== INI crearPersona ===");
		ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
		PersonaDTO res = this.admin.crearPersona(dto, ic);
		this.log.debug("===== FIN crearPersona ===\n {}", dto.toString());
		return res;
	}
	
	@Override
	public List<PersonaDTO> obtenerPersonas(HttpServletRequest request) throws ServiceException {
		try{	
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			this.log.debug("===== INI obtenerPersonas ===");
			List<PersonaDTO> dto = this.admin.obtenerPersonas(ic);
			this.log.debug("===== FIN obtenerPersonas ===\n {}", dto.toString());
			return dto;
		} catch (ServiceException e){
			logger.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			logger.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	
	}
	
	@Override
	public List<EscribanosDTO> obtenerEscribanos() throws ServiceException {
		this.log.debug("===== INI obtenerEscribanos ===");
		List<EscribanosDTO> dto = this.admin.obtenerEscribanos();
		this.log.debug("===== FIN obtenerPersonas ===\n {}", dto.toString());
		return dto;
	}

	@Override
	public List<PersonaInfoDTO> buscarPersonas( PersonaDTO dto,HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			this.log.debug("===== INI obtenerPersonas ===");
			List<PersonaInfoDTO> list = this.admin.buscarPersonas(dto,ic);
			this.log.debug("===== FIN obtenerPersonas ===\n {}", dto.toString());
			return list;
		} catch (ServiceException e){
			logger.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			logger.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
		
	}	
	
	
	@Override
	public PersonaInfoDTO obtenerPersonaInfo(Long id) throws ServiceException {
		this.log.debug("===== INI obtenerPersonaInfo ===");
		PersonaInfoDTO dto = null;
		try {
			dto = this.admin.obtenerPersonaInfo(id);
		} catch ( ServiceException e ) {
			this.log.error(e.toString(), e);
			throw e;
		}
		this.log.debug("===== FIN obtenerPersonaInfo ===\n {}", dto.toString());
		return dto;
	}
	
	@Override
	public PersonaInfoParaControlDTO getPersonaByPaisDocumento(PersonaQueryDTO values) throws ServiceException {
		PersonaInfoParaControlDTO dto = null;
		try {
			dto = this.admin.getPersonaByPaisDocumento(values);
		} catch ( ServiceException e ) {
			this.log.error(e.toString(), e);
			throw e;
		}
		return dto;
	}

//	@Override
//	public List<ClienteDTO> obtenerClientes() throws ServiceException {
//		this.log.debug("===== INI obtenerClientes ===");
//		List<ClienteDTO> dto = this.admin.obtenerClientes();
//		this.log.debug("===== FIN obtenerClientes ===\n {}", dto.toString());
//		return dto;
//	}
//
//	@Override
//	public ClienteInfoDTO obtenerCliente(Long id) throws ServiceException {
//		this.log.debug("===== INI obtenerCliente ===");
//		ClienteInfoDTO dto = this.admin.obtenerCliente(id);
//		this.log.debug("===== FIN obtenerCliente ===\n {}", dto.toString());
//		return dto;
//	}
//
//	@Override
//	public ClienteDTO actualizarCliente(ClienteDTO dto) throws ServiceException {
//		this.log.debug("===== INI actualizarCliente ===");
//		ClienteDTO res = this.admin.actualizarCliente(dto);
//		this.log.debug("===== FIN actualizarCliente ===\n {}", dto.toString());
//		return res;
//	}
//
//	@Override
//	public void eliminarCliente(Long id) throws ServiceException {
//		this.log.debug("===== INI eliminarCliente ===");
//		this.admin.eliminarCliente(id);
//		this.log.debug("===== FIN eliminarCliente ===\n {}", id);
//	}
//
//	@Override
//	public ClienteDTO crearCliente(ClienteDTO dto) throws ServiceException {
//		this.log.debug("===== INI crearCliente ===");
//		ClienteDTO res = this.admin.crearCliente(dto);
//		this.log.debug("===== FIN crearCliente ===\n {}", dto.toString());
//		return res;
//	}

	@Override
	public void actualizarTelefono(TelefonoDTO dto) throws ServiceException {
		this.log.debug("===== INI actualizarTelefono ===");
		this.admin.actualizarTelefono(dto);
		this.log.debug("===== FIN actualizarTelefono ===\n {}", dto.toString());
	}

	@Override
	public void eliminarTelefono(TelefonoDTO dto) throws ServiceException {
		this.log.debug("===== INI eliminarTelefono ===");
		this.admin.eliminarTelefono(dto);
		this.log.debug("===== FIN eliminarTelefono ===\n {}", dto.toString());
	}

	@Override
	public TelefonoDTO crearTelefono(TelefonoDTO dto) throws ServiceException {
		this.log.debug("===== INI crearTelefono ===");
		TelefonoDTO res = this.admin.crearTelefono(dto);
		this.log.debug("===== FIN crearTelefono ===\n {}", dto.toString());
		return res;
	}

	@Override
	public DomicilioDTO actualizarDomicilio(DomicilioDTO dto) throws ServiceException {
		this.log.debug("===== INI actualizarDomicilio ===");
		DomicilioDTO res = this.admin.actualizarDomicilio(dto);
		this.log.debug("===== FIN actualizarDomicilio ===\n {}", dto.toString());
		return res;
	}

	@Override
	public void eliminarDomicilio(Long id) throws ServiceException {
		this.log.debug("===== INI eliminarDomicilio ===");
		this.admin.eliminarDomicilio(id);
		this.log.debug("===== FIN eliminarDomicilio ===\n {}", id);
	}

	@Override
	public DomicilioDTO crearDomicilio(DomicilioDTO dto) throws ServiceException {
		this.log.debug("===== INI crearDomicilio ===");
		DomicilioDTO res = this.admin.crearDomicilio(dto);
		this.log.debug("===== FIN crearDomicilio ===\n {}", dto.toString());
		return res;
	}

//	@Override
//	public ClienteInfoDTO crearClienteInfo(ClienteInfoDTO dto) throws ServiceException {
//		ClienteInfoDTO res = null;
//		this.log.debug("===== INI crearClienteInfo ===");
//		try {
//		   res = this.admin.crearClienteInfo(dto);
//		} catch ( ServiceException e ) {
//			this.log.error(e.toString(), e);
//			throw e;
//		}
//		this.log.debug("===== FIN crearClienteInfo ===\n {}", dto.toString());
//		return res;
//	}
//
//	@Override
//	public void actualizarClienteInfo(ClienteInfoDTO dto) throws ServiceException {
//		this.log.debug("===== INI actualizarClienteInfo ===");
//		try {
//		   this.admin.actualizarClienteInfo(dto);
//		} catch ( ServiceException e ) {
//			this.log.error(e.toString(), e);
//			throw e;
//		}
//		this.log.debug("===== FIN actualizarClienteInfo ===\n {}", dto.toString());
//	}
	
	@Override
	public PersonaInfoDTO crearPersonaInfo(PersonaInfoDTO dto, HttpServletRequest request) throws ServiceException {
		PersonaInfoDTO res = null;
		ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
		this.log.debug("===== INI crearPersonaInfo ===");
		try {
		   if(ic.getIdEscribano()!=null || !ic.getIdEscribano().equals("")){
			   dto.setIdEscribano(ic.getIdEscribano());
		   }
		   res = this.admin.crearPersonaInfo(dto, ic);
		} catch ( ServiceException e ) {
			this.log.error(e.toString(), e);
			throw e;
		}
		this.log.debug("===== FIN crearPersonaInfo ===\n {}", dto.toString());
		return res;
	}
	
	@Override
	public EscribanosDTO crearEscribano(EscribanosDTO dto, HttpServletRequest request) throws ServiceException {
		EscribanosDTO res = null;
		this.log.debug("===== INI crearEscribano===");
		ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
		try {
		   res = this.admin.crearEscribano(dto, ic);
		} catch ( ServiceException e ) {
			this.log.error(e.toString(), e);
			throw e;
		}
		this.log.debug("===== FIN crearEscribano ===\n {}", dto.toString());
		return res;
	}
	
	@Override
	public void actualizarPersonaInfo(PersonaInfoDTO dto, HttpServletRequest request) throws ServiceException {
		this.log.debug("===== INI actualizarPersonaInfo ===");
		ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());

		try {
		   if(ic.getIdEscribano()!=null){
				   dto.setIdEscribano(ic.getIdEscribano());
		   }
		   this.admin.actualizarPersonaInfo(dto, ic);
		} catch ( ServiceException e ) {
			this.log.error(e.toString(), e);
			throw e;
		}
		this.log.debug("===== FIN actualizarPersonaInfo ===\n {}", dto.toString());
	}
	
	/******* USUARIO *******/
	@Override
	public List<UsuarioDTO> listUsuario(HttpServletRequest request) throws ServiceException { 
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			List<UsuarioDTO> result = daoUsuario.listUsuario(ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public UsuarioDTO showUsuario(Long id, HttpServletRequest request) throws ServiceException { 
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			UsuarioDTO result = daoUsuario.getUsuario(id, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public UsuarioDTO saveUsuario(Long id, UsuarioDTO dto, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			UsuarioDTO result = daoUsuario.updateUsuario(id, dto, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public UsuarioDTO createUsuario(UsuarioDTO dto, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			UsuarioDTO result = daoUsuario.createUsuario(dto, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}
	
	@Override
	public UsuarioDTO validaUsuario(UsuarioDTO dto, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			UsuarioDTO result = daoUsuario.validaUsuario(dto.getUsername(), dto.getPassword(), ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public Response deleteUsuario(Long id, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			daoUsuario.deleteUsuario(id, ic);
			return Response.ok().build();
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}
	@Override
	public UsuarioDTO cambiarClave(Long id, UsuarioDTO dto, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			UsuarioDTO result = daoUsuario.actualizarClave(id, dto, ic);
			return result;
		}
		catch (ServiceException e){
			this.log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			this.log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}
	

	/******* FUNCIONALIDAD *******/
	@Override
	public List<FuncionalidadDTO> listFuncionalidad(HttpServletRequest request) throws ServiceException { 
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			List<FuncionalidadDTO> result = daoFuncionalidad.listFuncionalidad(ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public FuncionalidadDTO showFuncionalidad(Long id, HttpServletRequest request) throws ServiceException { 
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			FuncionalidadDTO result = daoFuncionalidad.getFuncionalidad(id, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public FuncionalidadDTO saveFuncionalidad(Long id, FuncionalidadDTO dto, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			FuncionalidadDTO result = daoFuncionalidad.updateFuncionalidad(id, dto, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public FuncionalidadDTO createFuncionalidad(FuncionalidadDTO dto, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			FuncionalidadDTO result = daoFuncionalidad.createFuncionalidad(dto, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public Response deleteFuncionalidad(Long id, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			daoFuncionalidad.deleteFuncionalidad(id, ic);
			return Response.ok().build();
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	/******* PERFIL *******/
	@Override
	public List<PerfilDTO> listPerfil(HttpServletRequest request) throws ServiceException { 
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			List<PerfilDTO> result = daoPerfil.listPerfil(ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public PerfilDTO showPerfil(Long id, HttpServletRequest request) throws ServiceException { 
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			PerfilDTO result = daoPerfil.getPerfil(id, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public PerfilDTO savePerfil(Long id, PerfilDTO dto, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			PerfilDTO result = daoPerfil.updatePerfil(id, dto, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public PerfilDTO createPerfil(PerfilDTO dto, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			PerfilDTO result = daoPerfil.createPerfil(dto, ic);
			return result;
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	@Override
	public Response deletePerfil(Long id, HttpServletRequest request) throws ServiceException {
		try {
			ic = (InvocationContext) request.getAttribute(this.config.getContextAttributeName());
			daoPerfil.deletePerfil(id, ic);
			return Response.ok().build();
		}
		catch (ServiceException e){
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (Exception e){
			log.error(e.getMessage(), e);
			throw new ServiceException(ErrorCode.INTERNAL_ERROR, "internal.dataAccessError");
		}
	}

	
	@Override
	public void eliminarPersonaInfo(Long id) throws ServiceException {
		this.log.debug("===== INI eliminarDomicilio ===");
		this.admin.eliminarPersonaInfo(id);
		this.log.debug("===== FIN eliminarDomicilio ===\n {}", id);
	}
	
}
